<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>日历</title>
    <style>
        body {
            background-color: skyblue;
        }

        ul {
            list-style: none;
            padding: 0;
        }

        .clearfix::after {
            content: "";
            clear: both;
            display: block;
        }

        .container {
            width: 370px;
            height: 450px;
            position: fixed;
            margin: auto;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            background: #fff;
            padding: 10px;
            user-select: none;
        }

        .time-box {
            background: #f5f6fa;
            padding: 10px;
        }

        .time-box .time {
            font-size: 40px;
        }

        .time-box .date {
            font-size: 13px;
        }

        .calendar-box {
            padding: 5px 10px;
        }

        .calendar-box .head {
            margin-bottom: 15px;
        }

        .calendar-box .head span {
            border: 1px solid #ccc;
            padding: 3px 7px;
            float: left;
            margin-right: 5px;
            font-size: 15px;
        }

        .calendar-box .head button {
            border: none;
            float: right;
            background-color: #fff;
            cursor: pointer;
            margin-left: 5px;
        }

        .calendar-box .head .prev-btn,
        .calendar-box .head .next-btn {
            /* 逆时针旋转 90 度，纵向拉伸为原来的 2 倍 */
            transform: rotate(-90deg) scaleY(2);
            color: #99abce;
        }

        .calendar-box .head .back-btn {
            color: #0090ff;
        }

        .calendar-box .title span {
            width: 50px;
            float: left;
            text-align: center;
        }

        .calendar-box .body li {
            width: 50px;
            float: left;
            text-align: center;
            height: 46px;
            box-sizing: border-box;
        }

        .calendar-box .body li:hover {
            border: 1px solid #99c2eb;
            /* 由于加了 box-sizing: border-box; 所以给盒子加边框时，会挤压内容区 */
            /* outline: 1px solid #99c2eb; */
        }

        /* 其他月份 */
        .calendar-box .body .other {
            color: #ccc;
        }

        .calendar-box .body .today {
            background-color: #0077fe;
            color: #fff;
        }

        .calendar-box .body .today span {
            color: #fff;
        }

        .calendar-box .body li span {
            display: block;
            color: #999;
            font-size: 13px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="time-box">
            <div class="time">18:08:31</div>
            <div class="date">2021年6月16日 五月初七</div>
        </div>
        <div class="calendar-box">
            <div class="head clearfix">
                <span class="year">2021年</span>
                <span class="month">06月</span>
                <button class="next-btn">&lt;</button>
                <button class="prev-btn">&gt;</button>
                <button class="back-btn">回到今天</button>
            </div>
            <div class="title clearfix">
            </div>
            <ul class="body clearfix">
            </ul>
        </div>
    </div>
    <script src="moment-with-locales.js"></script>
    <script src="calendar.js"></script>
    <script crossorigin="anonymous" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" src="//lib.baomitu.com/jquery/3.6.0/jquery.min.js"></script>
    <script>
        $(function () {
            var back_btn = $(".calendar-box .back-btn"),
                calendar_body = $(".calendar-box .body");

            // 设置语言环境
            moment.locale("zh-cn");
            var month = moment();

            function init() {
                // 启动定时器
                setInterval(function () {
                    $(".time-box .time").html(moment().format("HH:mm:ss"));
                }, 1000);

                // 更新日期
                update_date(month);
                back_btn.hide();
                // 设置日历头
                $(".calendar-box .title").html(
                    moment.weekdaysMin(true).map(item => `<span>${item}</span>`).join('')
                );

                render_time(month);
                render_calendar(month);
                bind_event();
            }

            init();

            // 更新日期（有农历）
            function update_date(moment_obj) {
                var lunar_calendar = calendar.solar2lunar(  // 公历转农历
                    moment_obj.year(),
                    moment_obj.month() + 1,
                    moment_obj.date()
                );
                $(".time-box .date").html(
                    moment_obj.format("ll") +
                    " " +
                    lunar_calendar.IMonthCn +
                    lunar_calendar.IDayCn
                );
            }

            // 渲染时间
            function render_time(moment_obj) {
                month = moment_obj;
                $(".calendar-box .year").html(moment_obj.year() + "年");
                $(".calendar-box .month").html(
                    moment_obj.month() + 1 + "月"
                );
            }

            // 渲染日历
            function render_calendar(moment_obj) {
                // 获取节日
                function get_festival(moment_obj) {
                    // 公历转农历
                    var lunar_calendar = calendar.solar2lunar(
                        moment_obj.year(),
                        moment_obj.month() + 1,
                        moment_obj.date()
                    );
                    // 传统节日
                    if (lunar_calendar.festival) return lunar_calendar.festival;
                    // 农历节日
                    if (lunar_calendar.lunarFestival) return lunar_calendar.lunarFestival;
                    // 节气
                    if (lunar_calendar.Term) return lunar_calendar.Term;
                    // 农历月
                    if (lunar_calendar.IDayCn === "初一") return lunar_calendar.IMonthCn;
                    // 农历
                    return lunar_calendar.IDayCn;
                }

                var start_day = moment_obj.clone().startOf("month"),
                    calendar_html = "";
                start_day.subtract(start_day.weekday(), "days");

                for (var i = 0; i < 42; i++) {
                    var lunar_calendar = get_festival(start_day),
                        data_time = start_day.format("YYYY-MM-DD"),
                        date = start_day.get("date"),
                        cls = "";

                    if (start_day.isSame(moment_obj, "month")) {
                        if (start_day.isSame(moment(), "date")) {
                            cls = "today";
                        }
                    } else {
                        cls = "other";
                    }
                    calendar_html += `<li class="${cls}" data-time="${data_time}">${date}<span>${lunar_calendar}</span></li>`;
                    start_day.add(1, "days");
                }
                calendar_body.html(calendar_html);
            }

            // 绑定事件
            function bind_event() {
                function toggle_month(moment_obj) {
                    // 如果是同一个月，隐藏返回按钮，否则，显示返回按钮
                    if (moment_obj.isSame(moment(), "month")) {
                        back_btn.hide();
                    } else {
                        back_btn.show();
                    }
                    render_time(moment_obj);
                    render_calendar(moment_obj);
                }

                $(".calendar-box .prev-btn").click(function () {
                    toggle_month(month.subtract(1, "months"));
                });

                $(".calendar-box .next-btn").click(function () {
                    toggle_month(month.add(1, "months"));
                });

                back_btn.click(function () {
                    month = moment();
                    update_date(month)
                    toggle_month(month);
                });

                calendar_body.on("click", "li", function () {
                    $(this).css("border", "1px solid #06c").siblings().css("border", "");
                    update_date(moment($(this).data("time")));
                });
            }
        });
    </script>
</body>

</html>